package br.com.lucasddaniel.merchanmobile.dao;

import java.util.Enumeration;
import java.util.Hashtable;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDiskIOException;
import android.database.sqlite.SQLiteOpenHelper;

/** Classe para persistencia. */
public class BluetoothAdaptadorBanco {

	private static DatabaseHelper dbHelper;
	private static SQLiteDatabase db;

	/** Classe de ajuda de acesso ao banco */
	private static class DatabaseHelper extends SQLiteOpenHelper {
		DatabaseHelper( Context context ) {
			super( context, BTEsquemaBanco.DATA_BASE_NAME, null, BTEsquemaBanco.CURRENT_DATABASE_VERSION );
		}

		@Override
		public void onCreate( SQLiteDatabase db ) {
			db.execSQL( BTEsquemaBanco.SQL_CREATE_TABLE );
		}

		@Override
		public void onUpgrade( SQLiteDatabase db, int oldVersion, int newVersion ) {
			db.execSQL( BTEsquemaBanco.SQL_DROP_TABLE );
		}
	}

	/**
	 * Abre conexao com o banco.
	 * 
	 * @param context
	 * @throws ExcessaoBanco
	 */
	public static void abre( Context context ) throws ExcessaoBanco {
		try {
			dbHelper = new DatabaseHelper( context );
			db = dbHelper.getWritableDatabase();
		} catch( SQLException sqle ) {
			throw new ExcessaoBanco( sqle.getMessage(), ExcessaoBanco.DATABASE_OPEN_FAIL );
		}
	}

	/**
	 * Fecha conexao com o banco.
	 * 
	 * @param context
	 * @throws ExcessaoBanco
	 */
	public static void fecha( boolean force ) throws ExcessaoBanco {
		if( ! force && ! db.isOpen() ) {
			throw new ExcessaoBanco( "Banco fechado", ExcessaoBanco.DATABASE_NOT_OPEN );
		}
		if( dbHelper != null ) {
			dbHelper.close();
		}
		dbHelper = null;
		db = null;
	}

	/**
	 * Consulta estado de conexao com o banco.
	 * 
	 */
	public static boolean estaAberto() {
		return( dbHelper != null && db != null && db.isOpen() );
	}

	/**
	 * Insere Device.
	 * 
	 * @param table
	 * @param initialValues
	 * @return
	 * @throws ExcessaoBanco
	 */
	public static int insere( String table, ContentValues initialValues ) throws ExcessaoBanco {
		try {
			long id = db.insertOrThrow( table, null, initialValues );
			if( id == - 1 ) {
				throw new ExcessaoBanco( "Nao conseguiu inserir o objeto na tabela '" + table + "'", ExcessaoBanco.DATABASE_INSERT_FAIL );
			}
			return ( int ) id;
		} catch( SQLiteDiskIOException diskIOException ) {
			throw new ExcessaoBanco( "Memoria insuficiente pra criar o item.", ExcessaoBanco.INSUFFICIENT_MEMORY );
		}
	}

	/**
	 * Atualiza Device.
	 * 
	 * @param table
	 * @param initialValues
	 * @return
	 * @throws ExcessaoBanco
	 */
	public static int atualizar( String table, ContentValues initialValues, String idColumnValue) throws ExcessaoBanco {
		try {
			long id = BluetoothAdaptadorBanco.db.update( table, initialValues, "endereco=?", new String[] { idColumnValue } );
			if( id == - 1 ) {
				throw new ExcessaoBanco( "Nao conseguiu atualizar o objeto na tabela '" + table + "'", ExcessaoBanco.DATABASE_UPDATE_FAIL );
			}
			return ( int ) id;
		} catch( SQLiteDiskIOException diskIOException ) {
			throw new ExcessaoBanco( "Memoria insuficiente pra criar o item.", ExcessaoBanco.INSUFFICIENT_MEMORY );
		} 
	}

	/**
	 * Deleta todos devices da base.
	 * 
	 * @param table
	 * @param idColumnValue
	 * @throws ExcessaoBanco
	 */
	public static void deletarDevices( String table, String idColumnValue ) throws ExcessaoBanco {
		try {
			BluetoothAdaptadorBanco.db.execSQL( "delete from " + table );
		} catch( SQLiteDiskIOException diskIOException ) {
			throw new ExcessaoBanco( "Memoria insuficiente para criar ou copiar itens.", ExcessaoBanco.INSUFFICIENT_MEMORY );
		}
	}

	/**
	 * Recupera os itens da base utilizando clausula where.
	 * 
	 * @param table
	 * @param filters
	 * @return
	 * @throws ExcessaoBanco
	 */
	public static Cursor getObjects( String table, Hashtable<String, String> filters ) throws ExcessaoBanco {
		Cursor cursorResult = null;
		String[] filterValues = new String[filters.size()];
		String whereClause = BluetoothAdaptadorBanco.createWhereClause( filters, null, filterValues );
		cursorResult = db.query( table, null, whereClause, filterValues, null, null, null );

		return cursorResult;
	}

	/**
	 * Clausula where.
	 * 
	 * @param filters
	 * @param tablePrefix
	 * @param filterValues
	 * @return
	 */
	private static String createWhereClause( Hashtable<String, String> filters, String tablePrefix, String[] filterValues ) {
		String whereClause = null;
		if( tablePrefix == null ) {
			tablePrefix = "";
		}
		if( filters.size() > 0 ) {
			whereClause = "";
			Enumeration<String> filterFields = filters.keys();
			int i = 0;
			while( filterFields.hasMoreElements() ) {
				String field = filterFields.nextElement();
				if( whereClause.length() > 0 ) {
					whereClause += " AND ";
				}
				whereClause += tablePrefix + field + " == ?";
				filterValues[i] = filters.get( field );
				i ++ ;
			}
		}
		return whereClause;
	}
}
